
import React, { useState } from 'react';
import Item from './item/index';
import './index.less';
import * as Interface from './interface';

// checked  0:未选中 1选中 2子元素部分选中
const UiTree = () => {
  const [list, setList] = useState<Array<Interface.ListItemT>>(Interface.treeOption);

  // 子项展开/收起
  function visibleChange(item: Interface.ListItemT) {
    item.visible = !item.visible;
    setList([...list]);
  }
  // 选中切换
  function checkedChange(item: Interface.ListItemT, indexList) {
    item.checked = item.checked == 0 ? 1 : 0;
    if (item.children) {
      for (let i = 0; i < item.children.length; i++) {
        checkedChildren(item.children[i], item.checked);
      }
    }
    setList([...list]);
    if (indexList.length !== 1) checkedFather(indexList);
  }
  // 子项检测
  function checkedChildren(item: Interface.ListItemT, value) {
    item.checked = value;
    setList([...list]);
    if (item.children) {
      for (let i = 0; i < item.children.length; i++) {
        checkedChildren(item.children[i], item.checked);
      }
    }
  }
  // 父级检测-获取到子项的索引-反推父项并核对节点状态
  function checkedFather(indexList) {
    let arr = recursionFn(indexList, list, 0);
    let count = 0;
    let len = arr.children.length;
    for (let i = 0; i < len; i++) {
      if (arr.children[i].checked === 2) {
        count = -1;
        break;
      }
      if (arr.children[i].checked === 1) count++;
    }
    if (count === 0) arr.checked = 0;
    else if (count === len) arr.checked = 1;
    else arr.checked = 2;
    setList([...list]);
    if (indexList.length > 2) {
      indexList.splice(indexList.length - 1, 1);
      checkedFather(indexList);
    }
  }
  // 通过索引反推获取父级
  function recursionFn(indexList, arr, index: number) {
    if (indexList.length - 2 == index) return arr[indexList[index]];
    if (index < indexList.length - 2) {
      let num = index + 1; //不可使用index++代替
      return recursionFn(indexList, arr[indexList[index]].children, num);
    }
  }

  // 树节点渲染
  function renderItem(newlist: Array<Interface.ListItemT>, num = 0, fatherIndex: any = []) {
    return newlist.map((item, index) => {
      if (!item.children || item.children.length == 0) {
        return (
          <Item
            checkedChange={checkedChange.bind(this, item, [...fatherIndex, index])}
            visibleChange={visibleChange.bind(this)}
            key={index}
            params={{ ...item, left: num }}
          />
        );
      } else {
        return (
          <div style={{ marginLeft: `${num}px` }} className="ui-tree-children" key={index}>
            <div className="ui-tree-father">
              <span onClick={visibleChange.bind(this, item)} className={`ui-tree-icon ui-tree-${item.visible ? '' : 'iconright'}`}>
                <i className="iconfont icon-caret-down"></i>
              </span>
              <Item
                checkedChange={checkedChange.bind(this, item, [...fatherIndex, index])}
                visibleChange={visibleChange.bind(this)}
                key={index}
                params={{ ...item, left: 0 }}
              />
            </div>
            <div
              style={{
                height: item.visible ? '' : '0px'
              }}
              className="ui-tree-panel"
            >
              {renderItem(item.children, 20, [...fatherIndex, index])}
            </div>
          </div>
        );
      }
    });
  }

  return <div className="ui-tree">{renderItem(list)}</div>;
};
export default UiTree;
